home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 40 / Amiga Format CD40 (1999-05-11)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-06].iso / -readerstuff- / paul_qureshi / formats / lwstuff.lzx / lwmp.txt < prev    next >
Text File  |  1999-02-04  |  3KB  |  159 lines

  1.  
  2. /*
  3.  * MOTMOTH.C -- Motion path implementation.  This provides a simple
  4.  * implementation of motions paths as defined by LightWave 3D.
  5.  *
  6.  * originally by    Allen Hastings
  7.  * modified by        Stuart Ferguson
  8.  *
  9.  *    1/23/96
  10.  */
  11.  
  12.  
  13. /*
  14.  * A motion tracks 9 channels (x, y, z position, h, p, b rotation angle,
  15.  * and x, y, z scale), although this number can vary.  Envelopes work the
  16.  * same way but track only one channel.
  17.  */
  18. #define NUM_CHAN     9
  19. typedef double         ChanVec[NUM_CHAN];
  20.  
  21.  
  22. /*
  23.  * Each KeyFrame in a motion has the value of the channels at that key,
  24.  * tension, contunity and bias spline controls, a linear flag and the
  25.  * frame at which the key is located (step).
  26.  */
  27. typedef struct st_KeyFrame {
  28.     ChanVec         cv;
  29.     double         tens, cont, bias;
  30.     int         linear;
  31.     int         step;
  32. } KeyFrame;
  33.  
  34.  
  35. /*
  36.  * A motion is just an array of `keys' KeyFrames and the total number of
  37.  * steps in the motion.
  38.  */
  39. typedef struct st_Motion {
  40.     KeyFrame    *keylist;
  41.     int         keys, steps;
  42. } Motion;
  43.  
  44.  
  45.  
  46. /*
  47.  * Compute Hermite spline coeficients for t, where 0 <= t <= 1.
  48.  */
  49.     static void
  50. Hermite (
  51.     double             t,
  52.     double            *h1,
  53.     double            *h2,
  54.     double            *h3,
  55.     double            *h4)
  56. {
  57.     double             t2, t3, z;
  58.  
  59.     t2 = t * t;
  60.     t3 = t * t2;
  61.     z = 3.0 * t2 - t3 - t3;
  62.  
  63.     *h1 = 1.0 - z;
  64.     *h2 = z;
  65.     *h3 = t3 - t2 - t2 + t;
  66.     *h4 = t3 - t2;
  67. }
  68.  
  69.  
  70. /*
  71.  * Compute the motion channel vector for the given step.  Step can be
  72.  * fractional but values correspond to frames.
  73.  */
  74.     void
  75. MotionCalcStep (
  76.     Motion            *mot,
  77.     ChanVec             resVec,
  78.     double             step)
  79. {
  80.     KeyFrame        *key0, *key1;
  81.     double             t, h1, h2, h3, h4, res, d10;
  82.     double             dd0a, dd0b, ds1a, ds1b;
  83.     double             adj0, adj1, dd0, ds1;
  84.     int             i, tlength;
  85.  
  86.     /*
  87.      * If there is but one key, the values are constant.
  88.      */
  89.     if (mot->keys == 1) {
  90.             for (i = 0; i < 9; i++)
  91.             resVec[i] = mot->keylist[0].cv[i];
  92.         return;
  93.     }
  94.  
  95.     /*
  96.      * Get keyframe pair to evaluate.  This should be within the range
  97.      * of the motion or this will raise an illegal access.
  98.      */
  99.     key0 = mot->keylist;
  100.     while (step > key0[1].step)
  101.         key0 ++;
  102.     key1 = key0 + 1;
  103.     step -= key0->step;
  104.  
  105.     /*
  106.      * Get tween length and fractional tween position.
  107.      */
  108.     tlength = key1->step - key0->step;
  109.     t = step / tlength;
  110.  
  111.     /*
  112.      * Precompute spline coefficients.
  113.      */
  114.     if (!key1->linear) {
  115.         Hermite (t, &h1, &h2, &h3, &h4);
  116.         dd0a = (1.0 - key0->tens) * (1.0 + key0->cont)
  117.              * (1.0 + key0->bias);
  118.         dd0b = (1.0 - key0->tens) * (1.0 - key0->cont)
  119.              * (1.0 - key0->bias);
  120.         ds1a = (1.0 - key1->tens) * (1.0 - key1->cont)
  121.              * (1.0 + key1->bias);
  122.         ds1b = (1.0 - key1->tens) * (1.0 + key1->cont)
  123.              * (1.0 - key1->bias);
  124.  
  125.         if (key0->step != 0)
  126.             adj0 = tlength / (double)(key1->step - key0->prev->step);
  127.         if (key1->step != mot->steps)
  128.             adj1 = tlength / (double)(key1->next->step - key0->step);
  129.     }
  130.  
  131.     /*
  132.      * Compute the channel components.
  133.      */
  134.     for (i = 0; i < NUM_CHAN; i++) {
  135.         d10 = key1->cv[i] - key0->cv[i];
  136.  
  137.         if (!key1->linear) {
  138.             if (key0->step == 0)
  139.                 dd0 = .5 * (dd0a + dd0b) * d10;
  140.             else
  141.                 dd0 = adj0 * (dd0a
  142.                     * (key0->cv[i] - key0->prev->cv[i])
  143.                     + dd0b * d10);
  144.  
  145.             if (key1->step == mot->steps)
  146.                 ds1 = .5 * (ds1a + ds1b) * d10;
  147.             else
  148.                 ds1 = adj1 * (ds1a * d10 + ds1b
  149.                     * (key1->next->cv[i] - key1->cv[i]));
  150.  
  151.             res = key0->cv[i] * h1 + key1->cv[i] * h2
  152.                 + dd0 * h3 + ds1 * h4;
  153.         } else
  154.             res = key0->cv[i] + t * d10;
  155.  
  156.         resVec[i] = res;
  157.     }
  158. }
  159.